This is an example to help demonstrate how to write DIRC macros. This macro automatically sets your Macintosh clock from a dialup time server.
This macro uses either the NIST (Boulder, CO) or Naval Observatory (Washington, DC) time server to determine the correct date and time for your Macintosh. In order to operate correctly, the 'map' control panel must have been used at some point to specify the location of your Macintosh. In addition, you must indicate whether you are on daylight savings time each time the macro is run.
*/
FUNC main()
{
INT win,fd,x,y,z;
STR utc,dst,srv,s;
STR format,click,phone;
STR pref = ".PREF:%AutoTime Prefs";
// keep "macro running" window from being displayed
WIN_RUNNING(0);
// constants for summary template
STR togdst = "Using Daylight Savings Time";
STR rad303 = "Institute of Standards (Boulder, CO)";
Use the output of the time server to set the Macintosh clock to the current time. Connecting to the time server provides a continuous output of time records. The two different time servers return records in different formats.
Wait for the time server to start sending data. Look for UTC because it appears in the data. Then wait for a couple seconds to process any data which may have been buffered by the modem during the initial connection.
*/
WT("UTC");
WT(200);
/*
Wait for two lines of input with identical lengths. This is an easy way to "get in sync" with the time server and get a complete line of time data.
*/
new_time = "";
DO {
old_time = new_time;
new_time = IN("^m");
IF (STR_LEN(new_time) < 5) { new_time = IN("^m"); }
} WHILE (STR_LEN(old_time) != STR_LEN(new_time));
/*
Because the time server may send linefeeds and other non-data at the
start/end of each line, it is important to make sure the beginning of the line contains normal data. The line should start with a digit.
*/
WHILE (STR_LEFT(new_time, 1) < "0") {
new_time = STR_MID(new_time, 1, 80);
}
/*
With the date/time field read, it is now possible to compute the offset between the Macintosh date and the real date. The Macintosh date is maintained as the number of elapsed seconds from Jan 1, 1904. The time server returns the date in modified julian day format. This means that date is expressed as the number of elapsed days from Nov 17, 1858 (actually it is really the number of elapsed days from Jan 1, 4713 B.C. mod 100000, but it is easier to think of it as the former). Converting from a Macintosh date to a julian date is really simple since all you need to do is convert from seconds to days (86400 seconds in a day). The "problem" is that the number which represents the Macintosh date (for any date past approx 1970) is larger than DIRC's largest positive integer. If you try and divide such a number, you get an invalid result. This can be avoided by subtracting 2398377600 (the number of elapsed seconds from Jan 1, 1904 to Jan 1, 1980) and making up the difference once the value is in julian format. Once converted to julian format, the offset between the Macintosh date and the time server date is determined which can later be used to "correct" the Macintosh clock.
The "trick" to getting a decent time estimate is to use the current server time to compute a "target" time. The "target" time is the time at which the macro will determine the offset between the Macintosh clock and the server clock. Once the offset between the two clocks is known, the rest of the macro is no longer "time critical". The target time is set 3 seconds later than the current time. This gives sufficient time for the macro to complete its computations and accurately synchronize the determination of the offset.
The NIST and Naval Observatory time servers return the time in different formats. Therefore, there are two different routine to extract the time depending on which server is being used. It is possible to determine the server type by looking at the length of the time record returned by the server. The NIST server returns more information (a larger record) than the Naval server.
The target time has now arrived (or at least is very close-- usually within 1 second which is good enough). Now figure out the offset by subtracting the server time from the Macintosh time. The 2147472000 is needed because the Macintosh time is expressed in elapsed seconds from January 1, 1904. This particular value is larger than the largest positive DIRC integer. In order to prevent an overflow, subtract 2398377600 from the time to turn it into a valid DIRC positive value. This works because the result is taken mod 86400 so as to get the offset relative to the current day. The resulting offset is in the range 0-86399. Values greater than 86400/2 are assumed to be negative and are changed to real negative values.